package com.sduept.nwld.dataserver.manager.transclac;

import com.sduept.nwld.dataserver.util.ElectricalUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

@Slf4j
public class TransformerShortShockCalc {
	/**
	 * 故障前3个周波数据
	 * 
	 */
	private List<HMLWaveData> before3waveData;
	/**
	 * 故障后5个周波数据（100-180ms）
	 */
	private List<HMLWaveData> after8waveData;
	private double u1n;//高压侧额定电压
	private double u2n=230d;//中压侧额定电压
	private double u3n;//低压侧额定电压
	private String transType; //变压器类型（用于设置低压侧接线方式）
	private List<Double[]> before3List = new ArrayList<Double[]>();
	private List<Double[]> after8List = new ArrayList<Double[]>();
	private boolean lowerCurrentIsZero = false;
	
	public TransformerShortShockCalc(double u1n,double u2n,double u3n,List<HMLWaveData> before3waveData,List<HMLWaveData> after8waveData,String transType){
		this.before3waveData = before3waveData;
		this.after8waveData = after8waveData;
		this.transType = transType;
		this.u1n = u1n;
		this.u2n = u2n;
		this.u3n = u3n;
	}
	
	public Double[] shockCalc(){
		Double[] result = new Double[9];
		//加判断。
		HMLWaveData list1 = before3waveData.get(0);
		lowerCurrentIsZero = IsLowerIsZero(list1);
		for(HMLWaveData f:before3waveData){
			Double[] d = clacWaveReactance(f);
			before3List.add(d);
		}
		for(HMLWaveData f:after8waveData){
			Double[] d = clacWaveReactance(f);
			after8List.add(d);
		}
		Double[] before4 = average(before3List);
		Double[] after8 = average(after8List);
		for(int i=0;i<9;i++){
			if(before4[i] != null){
				result[i] = Math.abs((before4[i]-after8[i])/before4[i]);
			}else{
				result[i] = null;
			}
		}
		return result;
	}
	public Double[] shockCalc(Integer preStartIndex,Integer preEndIndex,Integer postStartIndex,Integer postEndIndex){
		Double[] result = new Double[9];
		//加判断。
		HMLWaveData list1 = before3waveData.get(0);
		lowerCurrentIsZero = IsLowerIsZero(list1);
		for(HMLWaveData f:before3waveData){
			Double[] d = clacWaveReactance(f);
			before3List.add(d);
		}
		for(HMLWaveData f:after8waveData){
			Double[] d = clacWaveReactance(f);
			after8List.add(d);
		}
		Double[] before4;
		Double[] after8;
		if(preStartIndex != null && preEndIndex != null){
			List<Double[]> list = before3List.subList(preStartIndex, preEndIndex+1);
			before4 = average(list);
		}else{
			before4 = average(before3List);
		}
		if(postStartIndex != null && postEndIndex != null){
			List<Double[]> list = after8List.subList(postStartIndex, postEndIndex+1);
			after8 = average(list);
		}else{
			after8 = average(after8List);
		}
		for(int i=0;i<9;i++){
			if(before4[i] != null){
				result[i] = Math.abs((before4[i]-after8[i])/before4[i]);
			}else{
				result[i] = null;
			}
		}
		return result;
	}
	public boolean IsLowerIsZero(HMLWaveData data){
		Complex hIa = data.getHwd().getIa();
		Complex lIa = data.getLwd().getIa();
		Complex hIb = data.getHwd().getIb();
		Complex lIb = data.getLwd().getIb();
		Complex hIc = data.getHwd().getIb();
		Complex lIc = data.getLwd().getIb();
		//如果任意一个高压侧电流比低压侧电流大，则认为低压侧为0
		return compareAmplitude(hIa,lIa) || compareAmplitude(hIb,lIb) || compareAmplitude(hIc,lIc);
	}
	public boolean compareAmplitude(Complex a,Complex b){
		double aa =  a.getValue1()*a.getValue1()+a.getValue2()*a.getValue2();
		double ba =  b.getValue1()*b.getValue1()+b.getValue2()*b.getValue2();
		if(aa - ba>0){
			return true;
		}else{
			return false;
		}
	}

	/**
	 * 计算每个周波的各个相别，各个电压侧的阻抗
	 * @param f
	 * @return
	 */
	private Double[] clacWaveReactance(HMLWaveData f){
		Double[] result = new Double[9];
		WaveData h = f.getHwd();
		WaveData m = mediumVoltageTransform(f.getMwd());
		WaveData l=null;
		if("D".equals(transType))
			l= lowVoltageTransformS(f.getLwd());
		else if("Y".equals(transType))
			l = lowVoltageTransformY(f.getLwd());
		else{
			log.info("变压器类型有误");
			return result;
		}
		Double xa12 = null;
		Double xa13 = null;
		Double xa23 = null;
		Double xb12 = null;
		Double xb13 = null;
		Double xb23 = null;
		Double xc12 = null;
		Double xc13 = null;
		Double xc23 = null;
		if(!lowerCurrentIsZero){
			double[] xa = clacPhaseReactance2(h.getIa(),m.getIa(),l.getIa(),h.getUa(),m.getUa(),l.getUa());
			xa12 = xa[0];
			xa13 = xa[1];
			xa23 = xa[2];
			double[] xb = clacPhaseReactance2(h.getIb(),m.getIb(),l.getIb(),h.getUb(),m.getUb(),l.getUb());
			xb12 = xb[0];
			xb13 = xb[1];
			xb23 = xb[2];
			double[] xc = clacPhaseReactance2(h.getIc(),m.getIc(),l.getIc(),h.getUc(),m.getUc(),l.getUc());
			xc12 = xc[0];
			xc13 = xc[1];
			xc23 = xc[2];
			
			/*//A相 高中压侧的短路电抗 
			xa12 = clacPhaseReactance(h.getUa(),h.getIa(),m.getUa(),m.getIa());
			//A相 高低压侧的短路电抗
			xa13 = clacPhaseReactance(h.getUa(),h.getIa(),l.getUa(),l.getIa());
			//A相 中低压侧的短路电抗
			xa23 = clacPhaseReactance(m.getUa(),m.getIa(),l.getUa(),l.getIa());
			
			//B相 高中压侧的短路电抗
			xb12 = clacPhaseReactance(h.getUb(),h.getIb(),m.getUb(),m.getIb());
			//B相 高低压侧的短路电抗
			xb13 = clacPhaseReactance(h.getUb(),h.getIb(),l.getUb(),l.getIb());
			//B相 中低压侧的短路电抗
			xb23 = clacPhaseReactance(m.getUb(),m.getIb(),l.getUb(),l.getIb());
			
			//C相 高中压侧的短路电抗
			xc12 = clacPhaseReactance(h.getUc(),h.getIc(),m.getUc(),m.getIc());
			//C相 高低压侧的短路电抗
			xc13 = clacPhaseReactance(h.getUc(),h.getIc(),l.getUc(),l.getIc());
			//C相 中低压侧的短路电抗
			xc23 = clacPhaseReactance(m.getUc(),m.getIc(),l.getUc(),l.getIc());*/
		}else{
			//A相 高中压侧的短路电抗 
			xa12 = clacPhaseReactanceOnLower0(h.getUa(),h.getIa(),m.getUa());
			//A相 高低压侧的短路电抗
			xa13 = null;
			//A相 中低压侧的短路电抗
			xa23 = null;
			
			//B相 高中压侧的短路电抗
			xb12 = clacPhaseReactanceOnLower0(h.getUb(),h.getIb(),m.getUb());
			//B相 高低压侧的短路电抗
			xb13 = null;
			//B相 中低压侧的短路电抗
			xb23 = null;
			
			//C相 高中压侧的短路电抗
			xc12 = clacPhaseReactanceOnLower0(h.getUc(),h.getIc(),m.getUc());
			//C相 高低压侧的短路电抗
			xc13 = null;
			//C相 中低压侧的短路电抗
			xc23 = null;
		}
		result[0]=xa12;
		result[1]=xa13;
		result[2]=xa23;
		result[3]=xb12;
		result[4]=xb13;
		result[5]=xb23;
		result[6]=xc12;
		result[7]=xc13;
		result[8]=xc23;
		return result;
	}
	/**
	 * 求各个周波阻抗平均值
	 * @param list
	 * @return
	 */
	private Double[] average(List<Double[]> list){
		Double[] result = new Double[9];
		for(int i=0;i<9;i++){
			//检测阻抗是否未空。
			if(list.get(0)[i] != null){
				double v=0;
				for(Double[] ff:list){
					v +=ff[i];
				}
				result[i] = v/list.size();
			}else{
				result[i] = null;
			}
		}
		return result;
	}
	/**
	 * 计算阻抗
	 * @param u1
	 * @param i1
	 * @param u2
	 * @param i2
	 * @return
	 */
	private double clacPhaseReactance(Complex u1,Complex i1,Complex u2,Complex i2){
		Complex u =  ElectricalUtil.complexSubtraction(u1,u2);
		i2 = ElectricalUtil.complexMultiply(new Complex(-1,0),i2);
		double xa12 = clacPhaseReactanceFormula(i1,i2,u);
		return xa12;
	}
	public double[] clacPhaseReactance2(Complex i1,Complex i2,Complex i3,Complex u1,Complex u2,Complex u3){
		double[][] k = new double[6][3];
		k[0][0] = -1*i1.getValue2();
		k[0][1] = i2.getValue2();
		k[0][2] = 0;
		
		k[1][0] = i1.getValue1();
		k[1][1] = -1*i2.getValue1();
		k[1][2] = 0;
		
		k[2][0] = -1*i1.getValue2();
		k[2][1] = 0;
		k[2][2] = i3.getValue2();
		
		k[3][0] = i1.getValue1();
		k[3][1] = 0;
		k[3][2] = -1*i3.getValue1();
		
		k[4][0] = 0;
		k[4][1] = -1*i2.getValue2();
		k[4][2] = i3.getValue2();
		
		k[5][0] = 0;
		k[5][1] = i2.getValue1();
		k[5][2] = -1*i3.getValue1();
		
		double[][] kT = Matrix.getA_T(k);
		
		double[][] dU = new double[6][1];
		dU[0][0] = u1.getValue1()-u2.getValue1();
		dU[1][0] = u1.getValue2()-u2.getValue2();
		dU[2][0] = u1.getValue1()-u3.getValue1();
		dU[3][0] = u1.getValue2()-u3.getValue2();
		dU[4][0] = u2.getValue1()-u3.getValue1();
		dU[5][0] = u2.getValue2()-u3.getValue2();
		
		double[][] x = Matrix.multiplyMatrix(Matrix.multiplyMatrix(Matrix.getN(Matrix.multiplyMatrix(kT, k)),kT),dU);
		double x12 = x[0][0]+x[1][0];
		double x13 = x[0][0]+x[2][0];
		double x23 = x[1][0]+x[2][0];
		return new double[]{x12,x13,x23};
	}
	/**
	 * 计算低压侧为0的阻抗
	 * @param u1
	 * @param i1
	 * @param u2
	 * @param i2
	 * @return
	 */
	private double clacPhaseReactanceOnLower0(Complex u1,Complex i1,Complex u2){
		Complex u =  ElectricalUtil.complexSubtraction(u1,u2);
		double x = clacPhaseReactanceFormulaOnLower0(i1,u);
		return x;
	}
	
	/**
	 * 求二阶逆矩阵
	 * @param d
	 * @return
	 */
	private double[][] matrixT(double[][] d){
		double dd = d[0][0]*d[1][1] - d[0][1]*d[1][0];
		double[][] dd1 = new double[2][2];
		dd1[0][0] = d[1][1]/dd;
		dd1[0][1] = -d[0][1]/dd;
		dd1[1][0] = -d[1][0]/dd;
		dd1[1][1] = d[0][0]/dd;
		return dd1;
	}
	/**
	 * 计算电抗公式
	 * @param i1
	 * @param i2
	 * @param u
	 * @return
	 */
	private double clacPhaseReactanceFormula(Complex i1,Complex i2,Complex u){
		double[][] d = new double[2][2];
		d[0][0] = -1*i1.getValue2();
		d[0][1] = -1*i2.getValue2();
		d[1][0] = i1.getValue1();
		d[1][1] = i2.getValue1();
		double[][] newd1 = matrixT(d);
		
		double[][] newd2 = new double[2][1];
		newd2[0][0] = u.getValue1();
		newd2[1][0] = u.getValue2();
		
		double[][] temp = Matrix.multiplyMatrix(newd1, newd2);
		double result = temp[0][0]+temp[1][0];
		return result;
	}
	public double clacPhaseReactanceFormulaOnLower0(Complex i1,Complex u){
		Complex reac = ElectricalUtil.complexDivision(u, i1);
		return reac.getValue2();
	}
	/**
	 * 中压侧到高压侧归一转换
	 * @param w
	 */
	private WaveData mediumVoltageTransform(WaveData w){
		WaveData result =new WaveData();
		double k = u1n/u2n;
		Complex k12 = new Complex(k,0);
		Complex newUa = ElectricalUtil.complexMultiply(k12,w.getUa());
		Complex newUb = ElectricalUtil.complexMultiply(k12,w.getUb());
		Complex newUc = ElectricalUtil.complexMultiply(k12,w.getUc());
		Complex newIa = ElectricalUtil.complexDivision(w.getIa(),k12);
		Complex newIb = ElectricalUtil.complexDivision(w.getIb(),k12);
		Complex newIc = ElectricalUtil.complexDivision(w.getIc(),k12);
		result.setUa(newUa);
		result.setUb(newUb);
		result.setUc(newUc);
		result.setIa(newIa);
		result.setIb(newIb);
		result.setIc(newIc);
		return result;
	}
	/**
	 * 低压侧到高压侧归一转换 （Y接法）
	 * @param w
	 */
	private WaveData lowVoltageTransformY(WaveData w){
		WaveData result =new WaveData();
		double k = u1n/u3n;
		Complex k13 = new Complex(k,0);
		Complex newUa = ElectricalUtil.complexMultiply(k13,w.getUa());
		Complex newUb = ElectricalUtil.complexMultiply(k13,w.getUb());
		Complex newUc = ElectricalUtil.complexMultiply(k13,w.getUc());
		Complex newIa = ElectricalUtil.complexDivision(w.getIa(),k13);
		Complex newIb = ElectricalUtil.complexDivision(w.getIb(),k13);
		Complex newIc = ElectricalUtil.complexDivision(w.getIc(),k13);
		result.setUa(newUa);
		result.setUb(newUb);
		result.setUc(newUc);
		result.setIa(newIa);
		result.setIb(newIb);
		result.setIc(newIc);
		return result;
	}
	/**
	 * 低压侧到高压侧归一转换 （三角形接法）
	 * @param w
	 */
	private WaveData lowVoltageTransformS(WaveData w){
		WaveData result =new WaveData();
		double k = u1n/(Math.sqrt(3)*u3n);
		Complex k13 = new Complex(k,0);
		Complex u3ax = ElectricalUtil.complexSubtraction(w.getUa(),w.getUc());
		Complex u3ay = ElectricalUtil.complexSubtraction(w.getUb(),w.getUa());
		Complex u3az = ElectricalUtil.complexSubtraction(w.getUc(),w.getUb());
		
		//Complex i3ax = ElectricalUtil.complexDivision(ElectricalUtil.complexSubtraction(w.getIa(),w.getIc()),new Complex(3,0));
		//Complex i3by = ElectricalUtil.complexDivision(ElectricalUtil.complexSubtraction(w.getIb(),w.getIa()),new Complex(3,0));
		//Complex i3cz = ElectricalUtil.complexDivision(ElectricalUtil.complexSubtraction(w.getIc(),w.getIb()),new Complex(3,0));
		Complex i3ax = w.getIa();
		Complex i3by = w.getIb();
		Complex i3cz = w.getIc();
		
		
		Complex newUa = ElectricalUtil.complexMultiply(k13,u3ax);
		Complex newUb = ElectricalUtil.complexMultiply(k13,u3ay);
		Complex newUc = ElectricalUtil.complexMultiply(k13,u3az);
		Complex newIa = ElectricalUtil.complexDivision(i3ax,k13);
		Complex newIb = ElectricalUtil.complexDivision(i3by,k13);
		Complex newIc = ElectricalUtil.complexDivision(i3cz,k13);
		result.setUa(newUa);
		result.setUb(newUb);
		result.setUc(newUc);
		result.setIa(newIa);
		result.setIb(newIb);
		result.setIc(newIc);
		return result;
	}

	public List<Double[]> getBefore3List() {
		return before3List;
	}

	public List<Double[]> getAfter8List() {
		return after8List;
	}

}
